package main

import (
	"ctptrading/src"
	"encoding/csv"
	"fmt"
	"os"
	"sort"
	"strings"
	"time"

	"gitee.com/haifengat/goctp"
	"github.com/sirupsen/logrus"
)

var tradingDays []string

// readCalendar 取交易日历
func readCalendar() {
	cal, err := os.Open("calendar.csv")
	defer cal.Close()
	if err != nil {
		logrus.Error(err)
	}
	reader := csv.NewReader(cal)
	lines, err := reader.ReadAll()
	for _, line := range lines {
		if len(line) == 0 {
			continue
		}
		if line[1] == "true" {
			tradingDays = append(tradingDays, line[0])
		}
	}
	sort.Strings(tradingDays)
}

func main() {
	readCalendar()
	// Test()
	// return
	// 7*24
	curDate := time.Now().Format("20060102")
	for i, day := range tradingDays {
		cmp := strings.Compare(day, curDate)
		if cmp < 0 {
			continue
		}
		// 当前交易日8:45之前等待
		if startTime, _ := time.ParseInLocation("20060102 15:04:05", fmt.Sprintf("%s 08:45:00", day), time.Local); time.Now().Before(startTime) {
			logrus.Info("waiting for trading start at ", startTime)
			time.Sleep(startTime.Sub(time.Now()))
		} // 15:00前开启
		if startTime, _ := time.ParseInLocation("20060102 15:04:05", fmt.Sprintf("%s 15:00:00", day), time.Local); time.Now().Before(startTime) {
			Run()
		}
		// 当日有夜盘
		if strings.Compare(tradingDays[i+1], time.Now().AddDate(0, 0, 3).Format("20060102")) <= 0 {
			if startTime, _ := time.ParseInLocation("20060102 15:04:05", fmt.Sprintf("%s 20:45:00", day), time.Local); time.Now().Before(startTime) {
				logrus.Info("waiting for night open at ", startTime)
				time.Sleep(startTime.Sub(time.Now()))
			}
			// 夜盘开启
			Run()
		}
	}
}

func Test() {
	r, err := src.NewAfterSingle()
	if err != nil {
		logrus.Fatal("应用启动错误:", err)
	}
	defer r.Close()

	logrus.Info("waiting for trade api logged and quote subscripted.")
	err = r.StartCTP()
	if err != nil {
		logrus.Fatal("接口启动错误：", err)
	}
	orderKey := r.TrdAPI.ReqOrderInsert("fu2105", goctp.DirectionBuy, goctp.OffsetFlagOpen, 2450, 1)
	// 策略所用算法 if straName := strings.TrimPrefix(a.orderStrategyName, "order."); straName in qount01
	fmt.Print("|" + orderKey + "|")
	go r.RunOrder(orderKey)
	for {
		time.Sleep(10 * time.Second)
	}
}

// Run 运行
func Run() {
	r, err := src.NewAfterSingle()
	if err != nil {
		logrus.Fatal("应用启动错误:", err)
	}
	defer r.Close()

	logrus.Info("waiting for trade api logged and quote subscripted.")
	err = r.StartCTP()
	if err != nil {
		logrus.Fatal("接口启动错误：", err)
	}
	// 追单(协程)
	r.SubOrder()

	// 状态显示
	for {
		var cntNotClose = 0
		var cntTrading = 0
		time.Sleep(1 * time.Minute) // 每分钟判断一次
		// logrus.Info()
		r.TrdAPI.InstrumentStatuss.Range(func(k, v interface{}) bool {
			status := v.(*goctp.InstrumentStatus)
			if status.InstrumentStatus != goctp.InstrumentStatusClosed {
				cntNotClose++
			}
			if status.InstrumentStatus == goctp.InstrumentStatusContinous {
				cntTrading++
			}
			return true
		})
		// 全关闭 or 3点前全都为非交易状态
		if cntNotClose == 0 {
			logrus.Info("交易日结束：", r.TrdAPI.TradingDay)
			break
		}
		if time.Now().Hour() <= 3 && cntTrading == 0 {
			logrus.Info("夜盘结束!")
			break
		}
		if cntTrading > 0 && time.Now().Minute()%10 == 0 {
			logrus.Info("current avaliable: {", r.TrdAPI.InvestorID, ":", r.TrdAPI.Account.Available, "}")
		}
	}
}
